﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using NewFormatProject.Infrastructure.Atrributes;
using NewFormatProject.Infrastructure.Dto.Datas;
using NewFormatProject.Infrastructure.Dto.Requests.Objects;
using NewFormatProject.Infrastructure.Dto.Responses;
using NewFormatProject.Infrastructure.Dto.Responses.Objects;
using NewFormatProject.Infrastructure.EFCore;
using NewFormatProject.Server.EFCore;
using NewFormatProject.Server.Instances.Extends.Entitys;
using NewFormatProject.Server.Instances.Extends.Requests;
using NewFormatProject.Server.Interfaces;

namespace NewFormatProject.Server.Instances
{
    internal class RightConfigIOC
    {
        public SysRightConfigServerEF rightConfigServerEF { get; set; }
        public RightConfigDetailServerEF rightConfigDetailServerEF { get; set; }
        public JobServerEF jobServerEF { get; set; }
    }
    [InjectClass]
    public class RightConfigServer : IRightConfigServer
    {
        private readonly RightConfigIOC _rightConfigIOC;
        public RightConfigServer(DbContext dbContext)
        {
            _rightConfigIOC = new RightConfigIOC()
            {
                rightConfigServerEF = new SysRightConfigServerEF(dbContext),
                rightConfigDetailServerEF = new RightConfigDetailServerEF(dbContext),
                jobServerEF = new JobServerEF(dbContext)
            };
        }

        public async Task<ResponseApiDto> Add(RequestSysRightConfigsDto dto)
        {
            int affectedRows = 0;
            await _rightConfigIOC.rightConfigServerEF.ExecuteInTransactionAsync(async () =>
            {
                SysRightConfigs config = dto.ToEntity();
                affectedRows += await _rightConfigIOC.rightConfigServerEF.Add(config);
                foreach (var jobId in dto.jobIds)
                {
                    foreach (var rightId in dto.rightIds)
                    {
                        await _rightConfigIOC.rightConfigDetailServerEF.Add(new RightConfigDetails
                        {
                            RcdRightConfigId = config.RcId,
                            RcdJobId = jobId,
                            RcdRightId = rightId
                        });
                    }
                }
            });
            return ResponseApiDto.Create(affectedRows);
        }
        private bool Exist(int id)
        {
            return _rightConfigIOC.rightConfigServerEF.Query(d => d.RcId == id).Any();
        }
        public async Task<ResponseApiDto> Delete(RequestSysRightConfigsDto dto)
        {
            if (!Exist(dto.id))
            {
                return ResponseApiDto.Fail("该权限配置不存在");
            }
            int affectedRows = 0;
            await _rightConfigIOC.rightConfigServerEF.ExecuteInTransactionAsync(async () =>
            {
                affectedRows += await _rightConfigIOC.rightConfigDetailServerEF.Delete(_rightConfigIOC.rightConfigDetailServerEF.Query(d => d.RcdRightConfigId == dto.id));
                affectedRows += await _rightConfigIOC.rightConfigServerEF.Delete(dto.ToEntity());
            });
            return ResponseApiDto.Create(affectedRows);
        }


        public async Task<ResponseApiDto> Pagination(int page, int limit, string key)
        {
            List<ResponseSysRightConfigsDto> data = new List<ResponseSysRightConfigsDto>();
            var iq = _rightConfigIOC.rightConfigServerEF.Query(d => string.IsNullOrEmpty(key) || d.RcName.Contains(key) || d.RcDescription.Contains(key));
            List<SysRightConfigs> configs = await iq.Skip((page - 1) * limit).Take(limit).ToListAsync();
            foreach (var config in configs)
            {
                data.Add(config.ToResponseDto());
            }
            return ResponseApiDto.Success("数据已获取", new PaginationData { data = data, total = await iq.CountAsync() });
        }

        public async Task<ResponseApiDto> Update(RequestSysRightConfigsDto dto)
        {
            int affectedRows = 0;
            await _rightConfigIOC.rightConfigServerEF.ExecuteInTransactionAsync(async () =>
            {
                SysRightConfigs config = dto.ToEntity();
                //更新对象本身
                affectedRows += await _rightConfigIOC.rightConfigServerEF.UpdateAllProperNotNull(config);
                //删除对象详情
                affectedRows += await _rightConfigIOC.rightConfigDetailServerEF.Delete(_rightConfigIOC.rightConfigDetailServerEF.Query(d => d.RcdRightConfigId == config.RcId));
                //添加对象详情
                foreach (var jobId in dto.jobIds)
                {
                    foreach (var rightId in dto.rightIds)
                    {
                        await _rightConfigIOC.rightConfigDetailServerEF.Add(new RightConfigDetails
                        {
                            RcdRightConfigId = config.RcId,
                            RcdJobId = jobId,
                            RcdRightId = rightId
                        });
                    }
                }
            });

            return ResponseApiDto.Create(affectedRows);
        }

        public async Task<ResponseApiDto> Detail(int id)
        {
            if (!Exist(id))
            {
                return ResponseApiDto.Fail("该权限配置不存在");
            }
            ResponseSysRightConfigsDto response =(await _rightConfigIOC.rightConfigServerEF.Query(d => d.RcId == id).SingleAsync()).ToResponseDto();
            List<int> jobIds = await _rightConfigIOC.rightConfigDetailServerEF.Query(d => d.RcdRightConfigId == id).Select(d => d.RcdRightId).Distinct().ToListAsync();
            response.jobs =(await _rightConfigIOC.jobServerEF.Query(d => jobIds.Contains(d.JId)).ToListAsync()).Select(d=>d.ToResponseDto()).ToList();
            response.rightIds =await _rightConfigIOC.rightConfigDetailServerEF.Query(d => d.RcdRightConfigId == id).Select(d => d.RcdRightId).Distinct().ToListAsync();
            return ResponseApiDto.Success("数据以获取", response);
        }
    }
}
